/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <sf-grid class="webserice-table">
        <sf-table
            ref="serviceTable"
            :options="options_fix">
            <sf-table-column :default-width="40"
                             type="index">
                <lang>序号</lang>
            </sf-table-column>
            <sf-table-column data-index="readableName"
                             :default-width="130">
                <lang>服务名称</lang>
            </sf-table-column>
            <sf-table-column data-index="status"
                             :default-width="80">
                <lang>服务状态</lang>
            </sf-table-column>
            <sf-table-column data-index="modelName"
                             :default-width="80">
                <lang>对应模型</lang>
            </sf-table-column>
            <sf-table-column data-index="minReplicas"
                             :default-width="60">
                <lang>最小实例数</lang>
            </sf-table-column>
            <sf-table-column data-index="maxReplicas"
                             :default-width="60">
                <lang>最大实例数</lang>
            </sf-table-column>
            <sf-table-column data-index="url"
                             :default-width="200">
                <lang>服务URL</lang>
            </sf-table-column>
            <sf-table-column data-index="run_time"
                             :default-width="90">
                <lang>运行环境</lang>
            </sf-table-column>
            <sf-table-column data-index="description"
                             :default-width="120">
                <lang>描述</lang>
            </sf-table-column>
            <sf-table-column data-index="opr"
                             :default-width="100">
                <lang>操作</lang>
            </sf-table-column>
            <!--额外操作-->

            <template slot="modelName"
                      slot-scope="{record}">
                <span>{{ record.default.modelName }}</span>
            </template>
            <template slot="minReplicas"
                      slot-scope="{record}">
                <span>{{ record.default.minReplicas }}</span>
            </template>
            <template slot="maxReplicas"
                      slot-scope="{record}">
                <span>{{ record.default.maxReplicas }}</span>
            </template>
            <template slot="status"
                      slot-scope="{record}">
                <span
                    class="common-status"
                    :class="serviceStatusClass(record.status)">
                </span>
                <sf-fieldtip v-if="record.status==='failed'"
                             class="failed-tips">
                    <lang>失败原因可能是：资源不够、模型或镜像错误，请检查后再次尝试。</lang>
                </sf-fieldtip>
            </template>
            <template slot="url"
                      slot-scope="{record}">
                <div class="formal-url">
                    <span :title="record.url"
                          class="sfv-ellipsis common-url">{{ record.url || '-' }}</span>
                    <span v-if="record.url"
                          v-clipboard:copy="record.url"
                          v-clipboard:success="_copySuccess"
                          :title="_('复制URL')"
                          class="icon iconfont iconfuzhi"></span>
                </div>
            </template>
            <template slot="run_time"
                      slot-scope="{record}">
                <div class="run-time__list">
                    <div class="run-time">
                        <span class="name">CPU:</span>
                        <span class="value">{{ record.default.cpuNum }}核</span>
                    </div>
                    <div class="run-time">
                        <span class="name">GPU:</span>
                        <span class="value">{{ record.default.gpuNum }}核</span>
                    </div>
                    <div class="run-time">
                        <span class="name">内存:</span>
                        <span class="value">{{ record.default.memorySize }}GB</span>
                    </div>
                </div>
            </template>
            <template slot="opr"
                      slot-scope="{record}">
                <div class="table-opr">
                    <a v-if="record.status==='ready'"
                       class="link-btn"
                       @click="_oprService(record)">
                        <lang>下线</lang>
                    </a>
                    <!-- 除了成功是已下线，其它3种情况都是显示上线 -->
                    <a v-if="record.status==='stopped' || record.status==='failed'"
                       class="link-btn"
                       @click="_oprService(record)">
                        <lang>上线</lang>
                    </a>
                    <a class="link-btn"
                       @click="_formalDynamicExpansion(record)">
                        <lang>动态扩容</lang>
                    </a>
                    <a class="link-btn"
                       @click="_deleteService(record)">
                        <lang>删除</lang>
                    </a>
                </div>
            </template>
        </sf-table>
    </sf-grid>
</template>
<script>
import deployUrlAdapter from 'src/home/mod_common/deploy_url_adapter';
const SERVICE_PETCH = deployUrlAdapter('services');
const SERVICE_DELETE = deployUrlAdapter('services');


import IntervalTask from 'src/util/interval_task';
import serviceTestForm from '../label_form/service_test_form.vue';

import formalDynamicExpansion from '../label_form/formal_dynamic_expansion.vue';

import {
    SERVICE_STATUS_NAME
} from '../const';

const PAGE_COUNT = 10;
const PAGE_COUNT_COUNT = 10000;

import { deepClone } from 'src/util/deep_clone';

export default {
    name: 'WebRelease',

    data () {
        return {
            emptyText:_('暂无服务管理，请在“模型仓库”页部署服务'),
            options_fix: {
                bufferView: false,

                // 配置这个后才可以实现保持勾选状态
                idProperty: 'id',
                selectionHide: true,
                forceFit: false,
                pagination: {
                    local:true,
                    activePage: 1,
                    pageSize: PAGE_COUNT,
                    pageSizes: [Number('10'), Number('20'), Number('50')],
                    layout: [ 'pager', 'jumper']
                }
            },
            searchParams:{
                pageSize: PAGE_COUNT_COUNT,
                pageNum: 0,
                keyword:''
            },
            intervalTask:null

        };
    },
    computed: {
        projectId () {
            return this.$route.query.projectId || '';
        }
    },
    mounted () {
        this.$mask();

        this.refreshGrid();

        this._createIntervalTask();
    },
    methods: {
        _createFormalDynamicExpansion () {
            if (!this.formalDynamicExpansion) {
                this.formalDynamicExpansion = this.$modal(formalDynamicExpansion, {
                    autoDestory: true
                });
            }
            return this.formalDynamicExpansion;
        },
        _formalDynamicExpansion (record) {
            let formWin = this._createFormalDynamicExpansion();
            formWin.formRoot.setJsonValue(record);
            formWin.open({
                title: _('动态扩容'),
                submit:()=>{
                    let ajaxParams = formWin.formRoot.getJsonValue();
                    this.ajaxformalDynamicExpansion(ajaxParams, formWin);
                }
            });
        },


        // 动态扩容
        async ajaxformalDynamicExpansion (params, formWin) {
            this.$mask();
            const SERVICE_UPDATE = deployUrlAdapter(`services/${params.id}`);
            let jsonData = await this.$ajax.patch(SERVICE_UPDATE, params);
            this.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('动态扩容失败'));
            }
            this.$ok(_('动态扩容成功'));
            formWin.hide();
            this.$mask();

            this.refreshGrid();
        },

        // 服务测试弹窗
        _createServiceTestWin () {
            this.serviceTestWin = this.$modal(serviceTestForm, {
                autoDestory: true
            });
            return this.serviceTestWin;
        },

        // 服务测试
        _serviceTest () {
            let formWin = this._createServiceTestWin();
            formWin.open({
                reset: true,
                title: _('服务测试'),
                buttons:[{
                    cls: 'btn-default',
                    text: '关闭',
                    actionName: 'cancel'
                }]
            });
        },

        _createIntervalTask () {
            let vm = this;
             this.intervalTask = new IntervalTask({
                fn: () => {
                     vm.refreshGrid().then(() => {
                        vm.intervalTask && vm.intervalTask.next();
                    });
                },
                interval: 10000,
                autoStart: true
            });
        },
        serviceStatusClass (status) {
            return `${SERVICE_STATUS_NAME[status]}`;
        },

        onEnterkey () {
            this.$mask();
            this.refreshGrid();
        },

        // 刷新grid
        async refreshGrid (params) {
            if (params) {
                this.searchParams.keyword = params.keyword;
            }
            this.searchParams.projectId = this.projectId;
            const SERVICE_GET = deployUrlAdapter(`projects/${this.projectId}/services`);
            let jsonData = await this.$ajax.get(SERVICE_GET, this.searchParams);
            let table = this.$refs.serviceTable;
            let {success, msg, data} = jsonData;
            this.$unmask();
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            };
            let { list } = data;
            table && table.getPagination().setTotal(data.total);
            table && table.loadData(list || []);
            if (!this.searchParams.keyword) {
                this.$emit('get-total', data.total);
            };
            this.refreshStatus();
        },
        async refreshStatus () {
            let table = this.$refs.serviceTable;
            let statusParams = deepClone(this.searchParams);
            Object.assign(statusParams, {withStatus:true});
            const SERVICE_GET = deployUrlAdapter(`projects/${this.projectId}/services`);
            let jsonData = await this.$ajax.get(SERVICE_GET, statusParams);
            let {success, msg, data} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            };
            let { list } = data;
            table && table.loadData(list || []);

            let startingLength = list.filter(item=>item.status === 'starting').length;

            // 存在启动中这种情况才会定时刷新,不存在loading则可以关掉定时器。
            if (!startingLength) {
                this.intervalTask && this.intervalTask.stop();
            } else {
                this.intervalTask && this.intervalTask.start();
            }
        },

        // 上下线
        _oprService (record) {
            let statusText = record.status === 'stopped' || record.status === 'failed' ? _('上线') :  _('下线');
            this.$confirm({
                title: _('确定'),
                subTitle: `确定要${statusText}${record.readableName}服务吗？`,
                msg: `服务${statusText}后将即时生效，可能对业务状态带来一定影响，请再次确认。`,
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this._ajaxOprService(record);
                    }
                }
            });
        },
        async _ajaxOprService (record) {
            let status = record.status === 'stopped' || record.status === 'failed' ? 'start' : 'stop';
            const PATCH_URL = `${SERVICE_PETCH}/${record.id}/${status}`;
            this.$mask();
            let jsonData = await this.$ajax.patch(PATCH_URL, {});
            this.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }

            let successText = record.status === 'stopped' ? _('启动中') : _('下线中');
            this.$ok(successText);
            if (record.status === 'stopped' || record.status === 'failed') {
                this.refreshGrid();
            } else {
                /* eslint-disable */
                setTimeout(() => {
                    this.refreshGrid();
                }, 5000);
            }
        },
        async ajaxDeleteService (record) {
            const DELETE_URL = `${SERVICE_DELETE}/${record.id}`;
            this.$mask();
            let jsonData = await this.$ajax.delete(DELETE_URL, {});
            this.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.$ok(_('删除服务成功'));
            this.$mask();
            this.refreshGrid();
        },
        _deleteService (record) {
            this.$confirm({
                title: _('提示'),
                subTitle: _('确定要删除{0}服务吗？', record.readableName),
                msg: '',
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this.ajaxDeleteService(record);
                    }
                }
            });
        },
        _copySuccess () {
            this.$ok(_('复制成功'));
        }


    },
    beforeDestroy () {
        this.intervalTask && this.intervalTask.stop();
        this.intervalTask = null;
    }
};
</script>
<style lang="less">
    .webserice-table {
        .sfv-toolbar_inner .sfv-btn{
            &.white{
                color: #fff;
            }
        }
        border: none;
        height: 100%;
        display: flex;
        flex-direction: column;

        .sfv-table {
            flex: 1;
        }
        .formal-url{
            .iconfuzhi{
                display: none;
                cursor: pointer;
                &:hover{
                    color: #204ed9;
                }
            }
            &:hover{
                .iconfuzhi{
                    display: inline-block;
                }
            }
        }
        .common-url{
            width: 95%;
            display: inline-block;
            vertical-align: bottom;
            margin-right: 2px;
        }
        .failed-tips{
            font-size: 16px;
            margin-top: -10px;
            margin-left: -2px;
        }


        .common-status{
            width: 64px;
            display: inline-block;
            height: 18px;
            &.stopped{
                background: url(../../../../img/service/stopped.svg);
                background-size: 100% 100%;
            }
            &.ready{
                background: url(../../../../img/service/ready.svg);
                background-size: 100% 100%;
            }
            &.starting{
                background: url(../../../../img/service/starting.svg);
                background-size: 100% 100%;
            }
            &.failed{
                background: url(../../../../img/service/failed.svg);
                background-size: 100% 100%;
            }
        }
    }


</style>
